iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 24
0
Modern Web

實作小範例入門 Vue & Vuex 2.0系列 第 24 篇

vue & vuex 24 - Login - I (action Promise、rouetr change)

  • 分享至 

  • xImage
  •  

前面做了幾個範例,今天我們來做一個登入頁面,試試看 vue-router 轉跳頁面以及 vuex 如何驗證搭配 Promise 使用。

vue & vuex 24 - Login

今天目標:

  1. 新增 login page
  2. 預設顯示 login
  3. 登入成功轉跳到 Hello page

Template use bootstrap example signin


login 算是全域行為,所以就不細分成 module 直接設計在 root 裡面。

vuex action Promise

有時候發出去的 action 是非同步事件,可是 vue UI 需要知道事件回傳的狀態是 success 或 error?

如果,這樣的狀態不太需要存在 vuex 裡面。

我們就可以利用 ES6 Promise 包裝,回傳 resolve 或 reject 來反應 UI 變化。

Promise

  • resolve 結果會在 then 裡面收到,
  • reject 結果會在 catch 裡面收到。

store/root.js

export const actions = {
  // login
  actionLogin ({ commit }, { email, password}) {
    // 目前沒找到比較好的範例 API,因此使用延遲 1.5s 模擬 ajax 以及簡單驗證。
    console.log('1. actionLogin');
    commit(types.LOADING, true); // 打開遮罩
    // 使用 Promise 包裝 API
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (email === 'vue_vuex2@ironman2017.tw' && password === '123') {
          console.log('2. Promise resolve');
          commit(types.LOADING, false); // 關閉遮罩
          resolve(); // resolve 結果會在 then 裡面收到
        }
        // error
        else {
          commit(types.LOADING, false); // 關閉遮罩
          reject(); // reject 結果會在 catch 裡面收到
        }
      }, 1500);
    });
  }
}

vue-router 轉跳

使用 $router.push 轉跳到 hello Page

// path
$router.push('/hello');
// name
$router.push({name: 'hello'});

login.vue

<template>
  <div id="login">
    <img src="static/img/ironman2017.jpg" class="responsive-img">
    <div class="container">
      <div class="form-signin">
        <h2 class="form-signin-heading">Please sign in</h2>
        <label for="email" class="sr-only">Email address</label>
        <input
          v-model="email"
          type="email"
          id="email"
          class="form-control"
          placeholder="Email address" required autofocus />
        <label for="inputPassword" class="sr-only">Password</label>
        <input
          v-model="password"
          @keyup.enter="login"
          type="password"
          id="inputPassword"
          class="form-control"
          placeholder="Password" required />
        <button 
          class="btn btn-lg btn-primary btn-block"
          type="submit"
          @click="login">
          Sign in
        </button>
        <br/>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'

export default {
  data () {
    return {
      email: 'vue_vuex2@ironman2017.tw',
      password: '',
    }
  },
  methods: {
    login () {
	  // 因為 action 包裝了 Promise 所以可以使用 then 和 catch 來接收非同步回傳狀態
      this.$store.dispatch('actionLogin', {
        email: this.email,
        password: this.password
      })
      .then(() => { // 接收 resolve
        console.log('3. get Promise resolve');
        setTimeout(() => {
          // 使用 $router.push 轉跳到 hello Page
          this.$router.push('/hello');
        }, 1000);
      })
      .catch(() => { // 接收 reject
        console.log('error get Promise reject!');
      });
    }
  }
}
</script>

Promise 流程

順序 框架 事件 回傳
1 Vue 按下登入按鈕 發動 action
2 vuex action 使用 ajax 調用 API
3-1 vuex ajax response success resolve
4-1 Vue action method .then 接收 resolve
3-2 vuex ajax response error reject
4-2 Vue action method .catch 接收 reject

vue &amp; vuex 24 Promise 流程


github 完整範例:

實作小範例入門 Vue & Vuex 2.0 - github 完整範例

使用 git checkout 切換每天範例。


上一篇
vue & vuex 23 - Open Data - III (搜尋條件、select option、v-else、watch)
下一篇
vue & vuex 25 - Login - II (router auth、rouetr beforeEach)
系列文
實作小範例入門 Vue & Vuex 2.0 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言